package org.openintents.filemanager;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.widget.RelativeLayout;
import android.widget.Toast;

import org.openintents.filemanager.util.UIUtils;
import org.openintents.intents.FileManagerIntents;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class SaveAsActivity extends Activity {
    protected static final int REQUEST_CODE_PICK_FILE_OR_DIRECTORY = 1;
    private Uri source;
    // Whether the scheme is file: (otherwise it's content:)
    private boolean fileScheme = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        UIUtils.setThemeFor(this);
        super.onCreate(savedInstanceState);
        //This activity is never shown to the user.
        setContentView(new RelativeLayout(this));
        Intent receivedIntent = getIntent();
        if (receivedIntent != null) {
            Uri uri = receivedIntent.getData();
            source = uri;
            if (uri.getScheme().equals("file"))
                processFile(uri);
            else if (uri.getScheme().equals("content"))
                processContent(uri);
        } else {
            Toast.makeText(this, R.string.saveas_no_file_picked, Toast.LENGTH_SHORT).show();
        }
    }

    private void startPickActivity(Intent intent) {
        try {
            startActivityForResult(intent, REQUEST_CODE_PICK_FILE_OR_DIRECTORY);
        } catch (ActivityNotFoundException e) {
            //Should never happen, but Java requires this catch
            Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
        }
    }

    private Intent createPickIntent() {
        return new Intent(FileManagerIntents.ACTION_PICK_FILE);
    }

    private void processFile(Uri uri) {
        fileScheme = true;
        Intent intent = createPickIntent();
        intent.setData(FileManagerProvider.getUriForFile(uri));
        startPickActivity(intent);
    }

    private void processContent(Uri uri) {
        fileScheme = false;
        String name = getPath(uri);
        Intent intent = createPickIntent();
        intent.setData(Uri.parse(name));
        startPickActivity(intent);
    }

    /*
     * Get the default path and filename for the saved file from content: scheme.
     * As the directory is always used the SD storage.
     * For GMail, the filename is the _display_name in its ContentProvider. Otherwise the file has
     * no name.
     * !IMPORTANT! When you add another "special" intent-filter like the one for GMail, consider,
     * if you could add also the code for finding out the filename.
     */
    private String getPath(Uri uri) {
        Uri sd = Uri.fromFile(Environment.getExternalStorageDirectory());
        if (uri.getHost().equals("gmail-ls")) {
            Cursor cur = managedQuery(uri, new String[]{"_display_name"}, null, null, null);
            int nameColumn = cur.getColumnIndex("_display_name");
            if (cur.moveToFirst()) {
                return sd.buildUpon().appendPath(cur.getString(nameColumn)).toString();
            }
        }
        return sd.getPath();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case REQUEST_CODE_PICK_FILE_OR_DIRECTORY:
                if (resultCode == RESULT_OK && data != null) {
                    Uri destinationUri = data.getData();
                    if (destinationUri != null && source != null) {
                        String destinationPath = destinationUri.getPath();
                        saveFile(new File(destinationPath));
                    }
                }
                break;
        }
        finish(); //End the activity
    }

    private void saveFile(File destination) {
        InputStream in = null;
        OutputStream out = null;
        try {
            if (fileScheme)
                in = new BufferedInputStream(new FileInputStream(source.getPath()));
            else
                in = new BufferedInputStream(getContentResolver().openInputStream(source));

            out = new BufferedOutputStream(new FileOutputStream(destination));
            byte[] buffer = new byte[1024];

            while (in.read(buffer) != -1)
                out.write(buffer);
            Toast.makeText(this, R.string.saveas_file_saved, Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            //Should never get here
            Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            Toast.makeText(this, R.string.saveas_error, Toast.LENGTH_SHORT).show();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }

        }
    }
}
